using System;
using System.Collections.Generic;
using System.Text;
using CodePlex.Resourceful.Wadl;
using System.Collections.Specialized;

namespace CodePlex.Resourceful
{
    internal static class InternalUtils
    {



        internal static string GetBasicAuthUsername(NameValuePairs headers)
        {
            return GetBasicAuth(headers).Value1;
        }


        internal static string GetBasicAuthPassword(NameValuePairs headers)
        {
            return GetBasicAuth(headers).Value2;
        }


        private static Tuple<string, string> GetBasicAuth(NameValuePairs headers)
        {

            if (!headers.ContainsKey(HttpHeader.Authorization))
            {
                return Tuple<string, string>.Empty;
            }

            string auth = headers[HttpHeader.Authorization];

            if (string.IsNullOrEmpty(auth))
            {
                return Tuple<string, string>.Empty;
            }

            auth = auth.Trim();

            if (!MonoCompat124.StartsWith(auth,"Basic ", StringComparison.InvariantCultureIgnoreCase))
            {
                return Tuple<string, string>.Empty;
            }


            string encoded = auth.Substring("Basic ".Length);
            byte[] decoded = Convert.FromBase64String(encoded);
            string[] parts = Encoding.ASCII.GetString(decoded).Split(':');
            return new Tuple<string, string>(parts[0], parts[1]);
        }





        internal static ApplicationResource FindResource(ReadOnlyList<ApplicationResource> resources, string relativeUri, NameValuePairs templateParameters)
        {
            string[] parts = relativeUri.Split('/');

            ApplicationResource next = resources.Find(delegate(ApplicationResource item)
            {
                if (item.Path == parts[0])
                {
                    return true;
                }

                if (item.TemplateParameters.Count > 0)
                {
                    foreach (TemplateParameter p in item.TemplateParameters)
                    {
                        if (templateParameters.ContainsKey(p.Name))
                        {
                            continue;
                        }
                        templateParameters[p.Name] = parts[0];
                        return true;
                    }

                   
                    
                }

                return false;
            });
            if (next == null || parts.Length == 1)
            {
                return next;
            }

            return next.FindResource(Fn.Join("/", Utils.Subarray(parts, 1)), templateParameters);
        }

        internal static ApplicationResource NewResource(List<ApplicationResource> resourceList, ReadOnlyList<ApplicationResource, string> resources, string path, params TemplateParameter[] templateParameters)
        {
            string[] parts = path.Split('/');


            if (parts.Length == 1)
            {
                ApplicationResource rt = new ApplicationResource(parts[0], templateParameters);
                resourceList.Add(rt);
                return rt;
            }
            else
            {

                ApplicationResource existing = resources[parts[0]];
                if (existing == null)
                {
                    ApplicationResource rt = new ApplicationResource(parts[0], templateParameters);
                    resourceList.Add(rt);
                    existing = rt;

                }


                return existing.NewResource(Fn.Join("/", Utils.Subarray(parts, 1)), templateParameters);
            }
        }




        internal static string RelativeUri(Uri rootUri, Uri requestUri)
        {
            if (!IsRelative(rootUri, requestUri))
            {
                return string.Empty;
            }
            return requestUri.ToString().Substring(rootUri.ToString().Length);

        }

        internal static bool IsRelative(Uri rootUri, Uri requestUri)
        {
            return rootUri.ToString().Length <= requestUri.ToString().Length; 

        }


        internal static ReadOnlyList<string> GetAcceptTypes(string[] acceptTypes)
        {
            if (acceptTypes == null)
            {
                return ReadOnlyList<string>.Empty;
            }
            // strip off the q= for now
            return new ReadOnlyList<string>(acceptTypes).ConvertAll<string>(delegate(string item)
                {
                    int i = item.IndexOf(";");
                    if (i > -1)
                    {
                        return item.Substring(0, i);
                    }
                    else
                    {
                        return item;
                    }

                });
        }

    }
}
